Rappel : le but de l'ACP est de trouver l'espace de représentation (engendré par les composantes principales ) qui représentent le mieux le nuage de points ( = les observations).
import numpy as np
import csv
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
sns.set(color_codes = True)
from data import *
from scipy import stats
from sklearn.decomposition import PCA
X1 = [3, 6, 4, 2, -1, 1]
X2 = [2, 4, 3, 3, 1, 1]
X = np.zeros((6, 2))
X[:,0] = X1.copy()
X[:,1] = X2.copy()
print('Données brutes : \n', X)
plt.figure(figsize = (9,7))
plt.plot(X1, X2 , 's')
plt.axis([-2,7, -2, 5])
plt.axvline(linewidth=2, color='blue')
plt.axhline(linewidth=2, color='blue')
#plt.legend(['données brutes'], fontsize = 14)
plt.title('Données brutes', fontsize = 20)
plt.xticks(fontsize = 18)
plt.yticks(fontsize = 18)
plt.xlabel('X1',fontsize = 18)
plt.ylabel('X2',fontsize = 18)
plt.show()
# Moyenne
m1 = np.mean(X1)
m2 = np.mean(X2)
print('Moyenne de X1 : ' + str(m1) + ', et moyenne de X2 :' + str(m2))
# Ecart-type
sig1 = np.std(X1)
sig2 = np.std(X2)
print('Ecart-type de X1 : ' + str(sig1) + ', et écart-type de X2 :' + str(sig2))
plt.figure(figsize = (9,7))
plt.plot(X1, X2 , 's')
plt.axvline(linewidth=2, color='blue')
plt.axhline(linewidth=2, color='blue')
plt.axis([-2,7, -2, 5])
plt.axvline(x = m1, linewidth=2, color='r')
plt.axhline(y = m2, linewidth=2, color='r')
plt.plot(m1, m2 , 'or')
plt.xticks(fontsize = 18)
plt.yticks(fontsize = 18)
plt.xlabel('X1',fontsize = 18)
plt.ylabel('X2',fontsize = 18)
plt.title('Représentation du centre du nuage de points' , fontsize = 20)
plt.show()
plt.figure(figsize = (9,7))
plt.plot(X1-m1, X2-m2 , 'o')
plt.axvline(linewidth=2, color='r')
plt.axhline(linewidth=2, color='r')
plt.axis([-4,5, -2, 5])
plt.title('Centrage du nuage de points', fontsize = 20)
plt.legend(['données brutes centrées'], fontsize = 18)
plt.xticks(fontsize = 18)
plt.yticks(fontsize = 18)
plt.xlabel('X1 - $m_1$',fontsize = 18)
plt.ylabel('X2 - $m_2$',fontsize = 18)
plt.show()
Xtilde = np.zeros((6, 2))
Xtilde[:,0] = (X1.copy() - m1)/sig1
Xtilde[:,1] = (X2.copy() - m2)/sig2
print('Données centrées et réduites : \n', Xtilde)
plt.figure(figsize = (9,7))
plt.plot(X1-m1, X2-m2 , 'o')
plt.plot(Xtilde[:,0], Xtilde[:,1], '*r' , markersize = 20 )
plt.axvline( linewidth=2, color='r')
plt.axhline( linewidth=2, color='r')
plt.axis([-4,5, -2, 5])
plt.title('Effet de la réduction sur le nuage de points centré', fontsize = 20)
plt.legend(['données brutes centrées', 'données centrées réduites'], fontsize = 18)
plt.xticks(fontsize = 18)
plt.yticks(fontsize = 18)
plt.xlabel('X1 - $m_1$',fontsize = 18)
plt.ylabel('X2 - $m_2$',fontsize = 18)
plt.show()
C = np.dot(Xtilde.T, Xtilde)/6.
C
acp = PCA(2) # Initialisation de l'objet PCA (qui va calculer les différentes étapes de l'ACP)
acp.fit(Xtilde) # Calcul des différentes étapes de l'ACP de Xtilde
acp.explained_variance_ # Valeurs propres ordonnées (décroissant)
acp.explained_variance_ratio_
Les composantes principales sont les deux nouvelles variables U1 et U2 portées par les axes u1 et u2 ci-dessous. La variance portée par la première composante principale u1 représente 94% de l'information totale contenue dans les variables. Ce qui veut dire qu'à elle seule, la variable U1 décrit relativement bien les données.
u1 = acp.components_[0]
print(u1)
u2 = acp.components_[1]
print(u2)
plt.figure(figsize = (9,7))
plt.plot(Xtilde[:,0], Xtilde[:,1], '*r' , markersize = 20)
plt.axvline( linewidth=2, color='r')
plt.axhline( linewidth=2, color='r')
plt.plot([-2*acp.components_[0][0] ,3*acp.components_[0][0] ],[-2*acp.components_[0][1],3*acp.components_[0][1] ], 'gray') # Premier vecteur propre
plt.plot([-acp.components_[1][0],acp.components_[1][0] ],[-acp.components_[1][1],acp.components_[1][1] ], 'gray') # Second vecteur propre
plt.plot([0,acp.components_[0][0] ],[0,acp.components_[0][1] ], linewidth=3) # Premier vecteur propre
plt.plot([0,acp.components_[1][0] ],[0,acp.components_[1][1] ],linewidth=3) # Second vecteur propre
plt.axis([-2, 2.5, -1.5, 2])
plt.xlabel('$\~X_1$', fontsize = 18)
plt.ylabel('$\~X_2$', fontsize = 18)
plt.xticks(fontsize = 18)
plt.yticks(fontsize = 18)
plt.title('Données centrées et réduites, u1 en bleu, u2 en vert', fontsize = 20)
plt.show()
Xproj = acp.transform(Xtilde)
print(Xproj)
plt.figure(figsize = (9,7))
plt.axvline( linewidth=2, color='gray')
plt.axhline( linewidth=2, color='gray')
plt.plot([0,1], [0,0],linewidth=3)
plt.plot([0,0], [0,1],linewidth=3)
plt.plot(Xproj[:,0], Xproj[:,1], '*r' , markersize = 20)
plt.axis([-2, 2.5, -1.5, 2])
plt.xlabel('$U_1$', fontsize = 18)
plt.ylabel('$U_2$', fontsize = 18)
plt.xticks(fontsize = 18)
plt.yticks(fontsize = 18)
plt.title('Données projetées sur u1 et u2', fontsize = 20)
plt.show()
np.var(Xproj[:,0])
np.var(Xproj[:,0])/(np.var(Xproj[:,0]) + np.var(Xproj[:,1]))
np.var(Xproj[:,1])
np.var(Xproj[:,1])/(np.var(Xproj[:,0]) + np.var(Xproj[:,1]))
np.var(X[:,0])/(np.var(X[:,0]) + np.var(X[:,1]))
np.var(X[:,1])/(np.var(X[:,0]) + np.var(X[:,1]))
$\rightarrow$ on a bien maximiser la variance portée par le premier axe en changeant d'espace de représentation
N = 30
X1 = np.random.randint(-10,10, N)
X2 = np.random.randint(-2,15, N)
X3 = 2*X1 -3*X2 + 4 + np.random.normal(0, 1.2, N) # Relation quasi linéaire entre X3 et les variables X1 et X2 (au bruit près)
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(X1,X2, X3)
ax.set_xlabel('X1')
ax.set_ylabel('X2')
ax.set_zlabel('X3')
plt.show()
# Calcul de la moyenne
m1 = np.mean(X1)
m2 = np.mean(X2)
m3 = np.mean(X3)
# Calcul de l'écart-type
sig1 = np.std(X1)
sig2 = np.std(X2)
sig3 = np.std(X3)
# Données centrées et réduites
Xtilde = np.zeros((N, 3))
Xtilde[:,0] = (X1 - m1)/sig1
Xtilde[:,1] = (X2 - m2)/sig2
Xtilde[:,2] = (X3 - m3)/sig3
C3D = np.dot(Xtilde.T, Xtilde)/N
print(C3D)
acp3 = PCA(3)
acp3.fit(Xtilde)
acp3.explained_variance_
np.cumsum(acp.explained_variance_ratio_)
Xproj3D = acp3.transform(Xtilde)
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(Xproj3D[:,0],Xproj3D[:,1],Xproj3D[:,2])
ax.set_xlabel('U1')
ax.set_ylabel('U2')
ax.set_zlabel('U3')
plt.show()
plt.figure(figsize = (6,6))
plt.axvline( linewidth=2, color='gray')
plt.axhline( linewidth=2, color='gray')
plt.plot([0,1], [0,0],linewidth=3)
plt.plot([0,0], [0,1],linewidth=3)
plt.plot(Xproj3D[:,0], Xproj3D[:,1], 'o')
plt.xlabel('$U_1$', fontsize = 14)
plt.ylabel('$U_2$', fontsize = 14)
plt.axis([-3, 3, -3,3])
plt.show()
plt.figure(figsize = (6,6))
plt.axvline( linewidth=2, color='gray')
plt.axhline( linewidth=2, color='gray')
plt.plot([0,1], [0,0],linewidth=3)
plt.plot([0,0], [0,1],linewidth=3)
plt.plot(Xproj3D[:,1], Xproj3D[:,2], 'o')
plt.xlabel('$U_2$', fontsize = 14)
plt.ylabel('$U_3$', fontsize = 14)
plt.axis([-3, 3, -3, 3])
plt.show()
plt.figure(figsize = (6, 6))
plt.axvline( linewidth=2, color='gray')
plt.axhline( linewidth=2, color='gray')
plt.plot([0,1], [0,0],linewidth=3)
plt.plot([0,0], [0,1],linewidth=3)
plt.plot(Xproj3D[:,0], Xproj3D[:,2], 'o')
plt.xlabel('$U_1$', fontsize = 14)
plt.ylabel('$U_3$', fontsize = 14)
plt.axis([-3, 3, -3, 3])
plt.show()
acp2 = PCA(2)
acp2.fit(Xtilde)
acp2.explained_variance_
np.cumsum(acp2.explained_variance_ratio_)
Xproj2 = acp2.transform(Xtilde)
plt.figure(figsize = (6,6))
plt.axvline( linewidth=2, color='gray')
plt.axhline( linewidth=2, color='gray')
plt.plot([0,1], [0,0],linewidth=3)
plt.plot([0,0], [0,1],linewidth=3)
plt.plot(Xproj2[:,0], Xproj2[:,1], 'o')
plt.xlabel('$U_1$', fontsize = 14)
plt.ylabel('$U_2$', fontsize = 14)
plt.axis([-3, 3, -3, 3])
plt.show()